/**
 * Copyright (c) 2018 苍穹跃龙
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.l.core.util;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import com.l.core.constant.Global;

/**
 * @author 严秋旺
 * @date 2017-11-03 15:22:10
 */
public class SecurityUtils {
    private static final String ENCODING = Global.ENCODING;
    /**
     * DES加解密的key
     */
    private static final String KEY_DES = "66ae9d2856364048ba5c2dd53eefe4bf";

    private static String byteToHex(byte[] bytes) {
        StringBuffer sb = new StringBuffer(bytes.length);
        String sTemp;
        for (int i = 0; i < bytes.length; i++) {
            sTemp = Integer.toHexString(0xFF & bytes[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }

    private static byte[] hexToByte(String content) {
        try {
            byte[] b = content.getBytes(ENCODING);
            if ((b.length % 2) != 0)
                throw new IllegalArgumentException("长度不是偶数");
            byte[] b2 = new byte[b.length / 2];
            for (int n = 0; n < b.length; n += 2) {
                String item = new String(b, n, 2);
                b2[n / 2] = (byte) Integer.parseInt(item, 16);
            }
            return b2;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * md5加密
     * 
     * @param src
     * @return
     */
    public static String md5(String str) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte[] b = md.digest();
            return byteToHex(b);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * DES加密
     * 
     * @param content
     * @return
     */
    public static String desEncrypt(String content) {
        return desEncrypt(content, KEY_DES);
    }

    public static String desEncrypt(String content, String key) {
        try {
            byte[] bytes = desEncrypt(content.getBytes(ENCODING), key.getBytes(ENCODING));
            return byteToHex(bytes);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static byte[] desEncrypt(byte[] content, byte[] keyBytes) {
        try {
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(keyBytes);
            // 创建一个密匙工厂，然后用它把DESKeySpec转换成
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey securekey = keyFactory.generateSecret(desKey);
            // Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance("DES");
            // 用密匙初始化Cipher对象
            cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
            // 现在，获取数据并加密
            // 正式执行加密操作
            return cipher.doFinal(content);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * DES解密
     * 
     * @param content
     * @return
     */
    public static String desDecrypt(String content) {
        return desDecrypt(content, KEY_DES);
    }

    public static String desDecrypt(String content, String key) {
        try {
            byte[] bytes = desDecrypt(hexToByte(content), key.getBytes(ENCODING));
            return new String(bytes, ENCODING);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static byte[] desDecrypt(byte[] content, byte[] keyBytes) {
        try {
            // DES算法要求有一个可信任的随机数源
            SecureRandom random = new SecureRandom();
            // 创建一个DESKeySpec对象
            DESKeySpec desKey = new DESKeySpec(keyBytes);
            // 创建一个密匙工厂
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            // 将DESKeySpec对象转换成SecretKey对象
            SecretKey securekey = keyFactory.generateSecret(desKey);
            // Cipher对象实际完成解密操作
            Cipher cipher = Cipher.getInstance("DES");
            // 用密匙初始化Cipher对象
            cipher.init(Cipher.DECRYPT_MODE, securekey, random);
            // 真正开始解密操作
            return cipher.doFinal(content);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
